import { Freer, Rebuilder, SandBox } from '../interfaces';
import LegacySandbox from './legacy/sandbox';
import { patchAtBootstrapping, patchAtMounting } from './patchers';
import ProxySandbox from './proxySandbox';
import SnapshotSandbox from './snapshotSandbox';
export { css } from './patchers';
export function createSandbox(appName, elementGetter, singular, scopedCSS, excludeAssetFilter) {
  let sandbox;

  if (window.Proxy) {
    sandbox = singular ? new LegacySandbox(appName) : new ProxySandbox(appName);
  } else {
    sandbox = new SnapshotSandbox(appName);
  }

  const bootstrappingFreers = patchAtBootstrapping(appName, elementGetter, sandbox, singular, scopedCSS, excludeAssetFilter);
  let mountingFreers = [];
  let sideEffectsRebuilders = [];
  return {
    proxy: sandbox.proxy,

    async mount() {
      sandbox.active();
      const sideEffectsRebuildersAtBootstrapping = sideEffectsRebuilders.slice(0, bootstrappingFreers.length);
      const sideEffectsRebuildersAtMounting = sideEffectsRebuilders.slice(bootstrappingFreers.length);

      if (sideEffectsRebuildersAtBootstrapping.length) {
        sideEffectsRebuildersAtBootstrapping.forEach(rebuild => rebuild());
      }

      mountingFreers = patchAtMounting(appName, elementGetter, sandbox, singular, scopedCSS, excludeAssetFilter);

      if (sideEffectsRebuildersAtMounting.length) {
        sideEffectsRebuildersAtMounting.forEach(rebuild => rebuild());
      }

      sideEffectsRebuilders = [];
    },

    async unmount() {
      sideEffectsRebuilders = [...bootstrappingFreers, ...mountingFreers].map(free => free());
      sandbox.inactive();
    }

  };
}